package com.eliza.base.views.learn.gestures

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.gestures.rememberScrollableState
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController

@Preview
@Composable
fun ScrollScreenPre() {
    ScrollScreen(rememberNavController())
}


@Composable
fun ScrollScreen(navController: NavController) {
    Column(modifier = Modifier.fillMaxWidth()) {
        ClickableSample()
        Row(modifier = Modifier.fillMaxWidth()) {
            ScrollBoxes()
            ScrollBoxesSmooth()
        }

        ScrollableSample()
    }
}

@Composable
fun ClickableSample() {
    val count = remember { mutableIntStateOf(0) }
    // content that you want to make clickable
    Text(
        text = count.intValue.toString(),
        modifier = Modifier.clickable { count.intValue += 1 }
    )
    Text(
        text = count.intValue.toString(),
        //通过 pointerInput 修饰符提供点按手势检测器：
        modifier = Modifier.pointerInput(Unit) {
            detectTapGestures(
                onPress = { /* Called when the gesture starts */ },
                onDoubleTap = { /* Called on Double Tap */ },
                onLongPress = { /* Called on Long Press */ },
                onTap = { /* Called on Tap */ }
            )
        }
    )
}

@Composable
fun ScrollBoxes() {
    Column(
        modifier = Modifier
            .background(Color.LightGray)
            .height(100.dp)
            .verticalScroll(rememberScrollState())
    ) {
        repeat(10) {
            Text("ScrollBox $it", modifier = Modifier.padding(2.dp))
        }
    }
}

@Composable
private fun ScrollBoxesSmooth() {
    val state = rememberScrollState() //更改滚动位置或获取当前状态
    LaunchedEffect(Unit) { state.animateScrollTo(100) }
    Column(
        modifier = Modifier
            .background(Color.LightGray)
            .height(400.dp)
            .padding(horizontal = 8.dp)
            .verticalScroll(state)
    ) {
        repeat(20) {
            Text("Item $it//${state.value}", modifier = Modifier.padding(5.dp))
        }
    }
}

//可滚动的修饰符
//scrollable  可检测滚动手势，但不会偏移其内容。
@Composable
fun ScrollableSample() {
    var offset by remember { mutableFloatStateOf(0f) }
    Box(
        Modifier
            .size(100.dp)
//scrollable 修饰符与滚动修饰符不同，区别在于 scrollable 可检测滚动手势，但不会偏移其内容。
            .scrollable(
                orientation = Orientation.Vertical,
//                此修饰符只有在指定了 ScrollableState 的情况下，才能正常工作。
//                构造 ScrollableState 时，您必须提供一个 consumeScrollDelta 函数，
//                该函数将在每个滚动步骤调用（通过手势输入、流畅滚动或快速滑动），并且增量以像素为单位。
//                该函数必须返回所消耗的滚动距离，以确保在存在具有 scrollable 修饰符的嵌套元素时，可以正确传播相应事件。
                state = rememberScrollableState { delta ->
                    offset += delta
                    delta
                }
            ).fillMaxWidth()
            .background(Color.LightGray),
        contentAlignment = Alignment.Center
    ) {
        Text(offset.toString(), fontSize = 30.sp)
    }
}